package com.bestdreamer.stream;

import com.bestdreamer.lambda.Introduce.Employee;
import org.junit.Test;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;

public class TestStreamAPI2 {

    List<Employee> employees = Arrays.asList(
            new Employee("张三",18,9999.99),
            new Employee("李四",28,5555.55),
            new Employee("王五",38,2222.22),
            new Employee("赵六",48,4444.44),
            new Employee("田七",58,7777.77),
            new Employee("田七",58,7777.77),
            new Employee("田七",58,7777.77)
    );

    // 中间操作

    /**
     * 筛选与切片
     * filter：接收 Lambda，从流中排除某些元素
     * limit：截断流，使其元素不超过给定数量
     * skip(n)：跳过元素，返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个，则返回一个空流，与 limit(n) 互补
     * distinct：筛选，通过流所生成元素的 hashCode() 和 equals() 去除重复元素
     */
    // 内部迭代：迭代操作由 Stream API 完成
    @Test
    public void test1(){
        // 中间操作：不会执行任何操作
        Stream<Employee> stream = employees.stream()
                .filter((e) -> {
                    System.out.println("Stream API 的中间操作");
                    return e.getAge() >35;
                });

        // 终止操作：一次性执行全部内容，即“惰性求值”
        stream.forEach(System.out::println);
    }

    // 外部迭代
    @Test
    public void test2(){
        Iterator<Employee> it = employees.iterator();

        while(it.hasNext()){
            System.out.println(it.next());
        }
    }

    @Test
    public void test3(){
        employees.stream()
                .filter((e) -> {
                    System.out.println("短路"); // && ||
                    return e.getSalary() > 5000;
                })
                .limit(2)
                .forEach(System.out::println);
    }

    @Test
    public void test4(){
        employees.stream()
                .filter((e) -> e.getSalary() > 5000)
                .skip(1)
                .distinct()
                .forEach(System.out::println);
    }

    /**
     * 映射
     * map —— 接收 Lambda，将元素转换成其他形式或提取信息。接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素。
     * flatMap —— 接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。
     */
    @Test
    public void test5(){
        List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");
        list.stream()
                .map(String::toUpperCase)
                .forEach(System.out::println);
    }


}
